package com.sunrise.financeiro.repositorio;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.sunrise.financeiro.repositorio.iface.RecorrenciaDao;
import com.sunrise.generico.acesso.DaoService;
import com.sunrise.generico.entidade.Recorrencia;

@Repository
public class RecorrenciaDaoImpl extends DaoService<Recorrencia> implements RecorrenciaDao {

	public List<Recorrencia> listarOrdenado() {
		List<Recorrencia> list = listar(Recorrencia.class);
		Collections.sort(list, new Comparator<Recorrencia>() {

			@Override
			public int compare(Recorrencia o1, Recorrencia o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public List<Recorrencia> search(Recorrencia ex) {
		List<Recorrencia> list =  searchByExample(Recorrencia.class, ex);
		Collections.sort(list, new Comparator<Recorrencia>() {

			@Override
			public int compare(Recorrencia o1, Recorrencia o2) {
				return o1.getNome().compareTo(o2.getNome());
			}
		});
		return list;
	}

	public Recorrencia getById(Long id) {
		return getById(id, Recorrencia.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Recorrencia> listarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Recorrencia.class);
		crit.add(Restrictions.ilike("nome", nome, MatchMode.ANYWHERE));
		return crit.list();
	}
	
	@Override
	public Recorrencia buscarPorNome(String nome) {
		Criteria crit = getSession().createCriteria(Recorrencia.class);
		crit.add(Restrictions.eq("nome", nome).ignoreCase());
		crit.add(Restrictions.eq("ativo", Boolean.TRUE));
		return (Recorrencia) crit.uniqueResult();
	}

	@Override
	public BigDecimal buscarSomaReceitaPorFiltro(Date dataInicio, Date dataFim, Long idConta, Long idCategoria) {
		Criteria crit = getSession().createCriteria(Recorrencia.class).setProjection(Projections.sum("valor"));
		
		if (dataInicio != null) {
			crit.add(Restrictions.ge("dataLancamento", dataInicio));
		}
		if (dataFim != null) {
			crit.add(Restrictions.le("dataLancamento", dataFim));
		}
		crit.createAlias("receita", "rec");

		if (idConta != null && idConta != 0) {
			crit.createAlias("rec.conta", "cont");
			crit.add(Restrictions.eq("cont.id", idConta));
		}

		if (idCategoria != null && idCategoria != 0) {
			crit.createAlias("rec.categoriaFinanceira", "cat");
			crit.add(Restrictions.eq("cat.id", idCategoria));

		}
		
		
		return (BigDecimal) crit.uniqueResult();
	}
	
	
	@Override
	public BigDecimal buscarSomaDespesaPorFiltro(Date dataInicio, Date dataFim, Long idConta, Long idCategoria) {
		Criteria crit = getSession().createCriteria(Recorrencia.class).setProjection(Projections.sum("valor"));
		
		if (dataInicio != null) {
			crit.add(Restrictions.ge("dataLancamento", dataInicio));
		}
		if (dataFim != null) {
			crit.add(Restrictions.le("dataLancamento", dataFim));
		}
		crit.createAlias("despesa", "desp");

		if (idConta != null && idConta != 0) {
			crit.createAlias("desp.conta", "cont");
			crit.add(Restrictions.eq("cont.id", idConta));
		}

		if (idCategoria != null && idCategoria != 0) {
			crit.createAlias("desp.categoriaFinanceira", "cat");
			crit.add(Restrictions.eq("cat.id", idCategoria));

		}
		
		
		return (BigDecimal) crit.uniqueResult();
	}



}
